﻿using DotNetCommon.Extensions;
using Newtonsoft.Json.Linq;

namespace DotNetCommon
{
    /// <summary>
    /// json帮助类
    /// </summary>
    public static class JsonHelper
    {
        /// <summary>
        /// 格式化json
        /// </summary>
        /// <param name="srcJson">原json</param>
        /// <param name="isIntend">是否缩进</param>
        /// <param name="removeComment">是否移除注释</param>
        /// <returns></returns>
        public static string Format(string srcJson, bool isIntend = true, bool removeComment = true)
        {
            if (srcJson.IsNullOrEmptyOrWhiteSpace()) return srcJson;
            bool isArray = IsArray(srcJson);
            if (isArray)
            {
                return JArray.Parse(srcJson, new JsonLoadSettings
                {
                    CommentHandling = removeComment ? CommentHandling.Ignore : CommentHandling.Load
                }).ToString(isIntend ? Newtonsoft.Json.Formatting.Indented : Newtonsoft.Json.Formatting.None);
            }
            else
            {
                return JObject.Parse(srcJson, new JsonLoadSettings
                {
                    CommentHandling = removeComment ? CommentHandling.Ignore : CommentHandling.Load
                }).ToString(isIntend ? Newtonsoft.Json.Formatting.Indented : Newtonsoft.Json.Formatting.None);
            }
        }

        /// <summary>
        /// 判断json是否是数组
        /// </summary>
        /// <param name="srcJson"></param>
        /// <returns></returns>
        public static bool IsArray(string srcJson)
        {
            if (srcJson.IsNullOrEmptyOrWhiteSpace()) return false;
            if (srcJson.StartsWith("[")) return true;
            if (srcJson.StartsWith("{")) return false;

            var index = 0;
            var len = srcJson.Length;
            var singleComment = false;
            var multiComment = false;
            var preMultiEnd = false;
            var preComment = false;
            while (index < len)
            {
                var c = srcJson[index];
                index++;
                if (singleComment)
                {
                    if (c == '\n')
                    {
                        singleComment = false;
                    }
                    continue;
                }
                if (multiComment)
                {
                    if (preMultiEnd)
                    {
                        if (c == '/')
                        {
                            multiComment = false;
                            continue;
                        }
                        else if (c == '*')
                        {
                            continue;
                        }
                        else
                        {
                            preMultiEnd = false;
                            continue;
                        }
                    }
                    else
                    {
                        if (c == '*') preMultiEnd = true;
                        continue;
                    }
                }

                //
                if (preComment)
                {
                    if (c == '*')
                    {
                        //进入多行
                        multiComment = true;
                        preComment = false;
                        continue;
                    }
                    else if (c == '/')
                    {
                        //进入单行
                        singleComment = true;
                        preComment = false;
                        continue;
                    }
                    preComment = false;
                    continue;
                }

                //啥模式也没有
                if (c == '/')
                {
                    //预进入单行或多行注释模式
                    preComment = true;
                    continue;
                }
                else if (c == '[')
                {
                    return true;
                }
                else if (c == '{')
                {
                    return false;
                }
                else
                {
                    continue;
                }
            }
            return false;
        }
    }
}
